package designPattern.Singleton;

/**
 * 懒加载:是
 * 线程安全:是
 *
 * 性能与安全平衡的方案 double-checked locking
 */
public class DCL {
    private volatile static DCL singleton;
    private DCL (){}
    public static DCL getSingleton() {
        if (singleton == null) { // 保证new了之后的得到实例的效率
            synchronized (DCL.class) {
                if (singleton == null) { //保证new的时候实例还没有被创建,否则别的线程会new很多实例
                    singleton = new DCL();

                    /**
                     * memory = allocate(); // 1.分配对象内存空间
                     * instance(memory)     // 2.初始化对象
                     * instance = memory    // 3. 设置实例指向刚分配的内存地址,此时instance != null
                     *
                     * 可能会出现指令重排
                     * 1-2-3
                     * 1-3-2
                     * 我的理解 先分配内存,再初始化对象,把对象指向分配的内存地址
                     *
                     * 1-3-2的解释: 1,3先执行了这时对象还未初始化,返回的是个未初始化完全对象,这时其他线程拿到单例判断不为空就返回了,拿到的是错误的对象
                     */
                }
            }
        }
        return singleton;
    }
}